package com.terry.bootdemo.api.interceptor;

import com.terry.bootdemo.api.apidao.ApiTokenDao;
import com.terry.bootdemo.api.entity.Token;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.security.SignatureException;

public class JwtTokenIntercepetor extends HandlerInterceptorAdapter {
   @Autowired ApiTokenDao apiTokenDao;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //自动派出生成token的路径 并且如果OPTIONS的请求是cors预跨域 设置allow对应头信息
        if(request.getRequestURI().equals("/token") || RequestMethod.OPTIONS.toString().equals(request.getMethod())){
            return true;
        }
        final String authHeader=request.getHeader("X-YAuth-Token");
        try {
            if (null == authHeader || authHeader.trim() == "") {
                throw new SignatureException("not found X-YAuth-Token");
            }
            final Claims claims = Jwts.parser().setSigningKey("terryjAuthy1.0.0")
                    .parseClaimsJwt(authHeader).getBody();
            Token token = apiTokenDao.findOne(new Specification<Token>() {
                @Override
                public Predicate toPredicate(Root<Token> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    criteriaQuery.where(criteriaBuilder.equal(root.get("appId"), claims.getSubject()));
                    return null;
                }
            });
            String tokenval = new String(token.getToken());
            //如果内存中不存在 提示客户端获取token
            if (tokenval == null || tokenval.trim() == "") {
                throw new SignatureException("not find token info , please get token info ");
            }
            //判断内存中的token是否与客户端一致
            if (!tokenval.equals(authHeader)) {
                throw new SignatureException("not find token info , please get token info ");
            }
        }catch (SignatureException | ExpiredJwtException e){
            PrintWriter writer=response.getWriter();
            writer.write("need available tolen");
            writer.close();
            return false;
        }
        return super.preHandle(request, response, handler);
    }
}
